/***
 * @Description: 本文件是关于ARP协议的相关数据结构定义和具体协议功能实现的头文件
 * @Author: Liverpool
 * @Date: 2024-06-06 00:29:22
 * @LastEditTime: 2024-06-06 00:30:39
 * @LastEditors: Liverpool
 */
#ifndef ARP_H
#define ARP_H

#include "list.h"
#include "ipaddr.h"
#include "ethernet.h"
#include "packet.h"

// 定义ARP协议的硬件类型
#define ARP_HW_ETHERNET 1 // ARP协议的以太网硬件类型

// 定义ARP协议的操作码
#define ARP_REQUEST 1 // 发送ARP请求
#define ARP_REPLY 2   // ARP请求的回应

// 定义ARP缓存表的表项分配方式
#define ARP_CACHE_ALLOC_FORCE 1   // ARP缓存表进行强制分配
#define ARP_CACHE_ALLOC_UNFORCE 0 // ARP缓存表不进行强制分配

// 定义ARP协议的数据包格式
#pragma pack(1)
typedef struct _arp_packet
{
    uint16_t hw_type;                        // 硬件类型
    uint16_t protocol_type;                  // 协议类型
    uint8_t hw_len;                          // 硬件长度
    uint8_t protocol_len;                    // 协议长度
    uint16_t operation_code;                 // 操作码
    uint8_t send_hwaddr[ETHERNET_HW_SIZE];   // 发送方硬件地址
    uint8_t send_ipaddr[IPV4_ADDR_SIZE];     // 发送方IP地址
    uint8_t target_hwaddr[ETHERNET_HW_SIZE]; // 目标方的硬件地址
    uint8_t target_ipaddr[IPV4_ADDR_SIZE];   // 目标方的IP地址
} D_ARP_Packet;
#pragma pack()

// ARP协议的缓存表的数据结构定义
typedef struct _arp_entry
{
    uint8_t ipaddr[IPV4_ADDR_SIZE];   // IP地址
    uint8_t hwaddr[ETHERNET_HW_SIZE]; // 硬件MAC地址

    enum
    {
        NET_ARP_FREE,     // 没有IP地址和mac地址(空状态)
        NET_ARP_WAITING,  // 发送IP地址请求，没有等到MAC地址的回应(ARP请求)
        NET_ARP_RESOLVED, // ARP请求完成，已经保存了响应的IP地址和MAC地址
    } state;              // 该缓存表节点的状态
    int ms;               // 超时
    int retry;            // 重试次数
    D_ListNode node;      // 缓存链表的节点
    D_List buf_list;      // 待发送的数据包链表

    D_Net_Interface *netif; // 需要进行发送的指定网卡
} D_ARP_Entry;

// ---------------------------------外部函数定义区-------------------------------
net_err_t arp_init(void);                                                              // arp模块的初始化函数
net_err_t arp_make_request(D_Net_Interface *netif, const D_IP_ADDR *dest);             // 进行ARP请求命令(请求包的发送)
net_err_t arp_make_gratuitous(D_Net_Interface *netif);                                 // 广播一个免费(无回报的)ARP包
net_err_t arp_in(D_Net_Interface *netif, D_Packet *buf);                               // 对输入的ARP包进行解析
net_err_t arp_resolve(D_Net_Interface *netif, const D_IP_ADDR *ipaddr, D_Packet *buf); // ARP协议的解析函数
void arp_cache_clear(D_Net_Interface *netif);                                          // 对ARP缓存表进行清空
const uint8_t *arp_find(D_Net_Interface *netif, D_IP_ADDR *ipaddr);                    // arp缓存表中根据IP地址查找mac地址
void arp_update_from_IP_packet(D_Net_Interface *netif, D_Packet *buf);                 // 从IP数据被中更新ARP缓存表

#endif // !ARP_H